package com.autoagent.ai_live_master.scriptGeneration.service.impl;


import com.autoagent.ai_live_master.common.model.ByteArrayMultipartFile;
import com.autoagent.ai_live_master.common.model.PageRequestVO;
import com.autoagent.ai_live_master.common.model.Payload;
import com.autoagent.ai_live_master.common.utils.AgentClient;
import com.autoagent.ai_live_master.common.utils.BeanConverter;
import com.autoagent.ai_live_master.common.utils.KbClient;
import com.autoagent.ai_live_master.common.utils.OssUtil;
import com.autoagent.ai_live_master.scriptGeneration.Enum.FileStatusEnum;
import com.autoagent.ai_live_master.scriptGeneration.dto.ProductMaterialDTO;
import com.autoagent.ai_live_master.scriptGeneration.entity.ProductMaterialFile;
import com.autoagent.ai_live_master.scriptGeneration.entity.ProductMaterials;
import com.autoagent.ai_live_master.scriptGeneration.mapper.ProductMaterialFileMapper;
import com.autoagent.ai_live_master.scriptGeneration.mapper.ProductMaterialsMapper;
import com.autoagent.ai_live_master.scriptGeneration.service.ProductMaterialsService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class ProductMaterialsServiceImpl implements ProductMaterialsService {
    
    @Autowired
    private ProductMaterialsMapper mapper;

    @Autowired
    private ProductMaterialFileMapper productMaterialFileMapper;
    
    @Autowired
    @Qualifier("productSearchAgentClient")
    private AgentClient agentClient;

    @Autowired
    private KbClient kbClient;

    @Autowired
    private OssUtil ossUtil;

    @Override
    public void addMaterial(ProductMaterialDTO uploadDTO) {
        log.info("开始处理文件上传 - 用户ID: {}, KB ID: {}",
                uploadDTO.getUserId(), uploadDTO.getKbId());

        Long userId = uploadDTO.getUserId();
        String fileName = uploadDTO.getFile().getOriginalFilename();

        // 预声明 fileRecord，在外层作用域可访问
        ProductMaterialFile fileRecord = new ProductMaterialFile();

        try {
            byte[] fileContent = uploadDTO.getFile().getBytes();

            // === 第一步：上传到 OSS ===
            log.info("上传文件到 OSS: {}", fileName);
            MultipartFile multipartFile = null;
            if (fileName != null) {
                multipartFile = new ByteArrayMultipartFile(fileContent, "file", fileName, Objects.requireNonNull(uploadDTO.getFile().getContentType()));
            }
            String ossFilePath = null;
            if (multipartFile != null) {
                ossFilePath = ossUtil.uploadLargeFile(multipartFile);
            }
            log.info("文件上传到 OSS 成功，路径: {}", ossFilePath);

            // === 第二步：创建中间记录（状态 PROCESSING） ===
            fileRecord.setUserId(userId);
            fileRecord.setFileName(fileName);
            fileRecord.setFilePath(ossFilePath);
            fileRecord.setStatus(FileStatusEnum.PROCESSING);
            fileRecord.setUploadTime(LocalDateTime.now());
            productMaterialFileMapper.insert(fileRecord); // 已生成 ID
            log.info("创建中间记录 ProductMaterialFile 成功 - ID: {}", fileRecord.getId());

            // === 第三步：上传到知识库 ===
            Map<String, Object> result = kbClient.uploadFileToKb(
                    uploadDTO.getKbId().intValue(),
                    fileContent,
                    fileName
            );
            Map<String, Object> data = (Map<String, Object>) result.get("data");

            // === 上传成功 → 更新状态为 SUCCESS ===
            fileRecord.setStatus(FileStatusEnum.SUCCESS);
            fileRecord.setDatasetId((Long) data.get("datasetId"));
            fileRecord.setRemarks("上传知识库成功");
            productMaterialFileMapper.updateById(fileRecord);
            log.info("更新 ProductMaterialFile 状态为 SUCCESS");

        } catch (Exception e) {
            log.error("文件上传处理失败 - 用户ID: {}, 错误: {}", uploadDTO.getUserId(), e.getMessage(), e);

            // === OSS已上传成功 → 尝试删除文件 ===
            if (fileRecord.getFilePath() != null) {
                try {
                    ossUtil.deleteFile(null,fileRecord.getFilePath());
                    log.info("已删除OSS中上传失败的文件: {}", fileRecord.getFilePath());
                } catch (Exception ossEx) {
                    log.warn("删除OSS文件失败: {}", ossEx.getMessage(), ossEx);
                }
            }

            // === 上传失败 → 更新状态为 FAIL ===
            if (fileRecord.getId() != null) {
                fileRecord.setStatus(FileStatusEnum.FAILED);
                fileRecord.setRemarks("上传知识库失败: " + e.getMessage());
                productMaterialFileMapper.updateById(fileRecord);
                log.info("更新 ProductMaterialFile 状态为 FAIL");
            } else {
                log.warn("未插入中间记录 ProductMaterialFile，无法更新状态");
            }

            throw new RuntimeException("文件上传失败", e);
        }
    }


    @Override
    public String searchProductMaterials(String query) {
        log.info("开始产品信息检索 - 查询内容: {}", query);
        
        try {
            // 构建请求payload
            log.debug("构建Agent请求payload - AgentId: {}", agentClient.getAgentId());
            Payload payload = Payload.builder()
                    .agentId(agentClient.getAgentId())
                    .userChatInput(query)
                    .build();
            
            // 调用Agent服务
            log.info("发送检索请求到Agent服务");
            String response = agentClient.chat_completions(payload);
            
            // 检查响应
            if (response == null || response.isEmpty()) {
                log.warn("Agent服务返回空响应");
                return "未找到相关产品信息";
            }
            
            log.info("产品信息检索成功 - 响应长度: {}", response.length());
            return response;
            
        } catch (Exception e) {
            log.error("产品信息检索失败 - 查询内容: {}, 错误信息: {}", query, e.getMessage(), e);
            throw new RuntimeException("产品信息检索失败: " + e.getMessage(), e);
        }
    }

    @Override
    public Page<ProductMaterialFile> getDatasetsByUserId(Long userId, Integer pageNum, Integer pageSize, String keyword) throws Exception {
        log.info("开始分页查询用户的产品素材列表 - 用户ID: {}, 页码: {}, 每页大小: {}, 关键字: {}", userId, pageNum, pageSize, keyword);
        try {
            Page<ProductMaterialFile> page = new Page<>(pageNum, pageSize);
            LambdaQueryWrapper<ProductMaterialFile> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ProductMaterialFile::getUserId, userId);

            // 如果有关键字，添加fileName字段的模糊匹配
            if (keyword != null && !keyword.trim().isEmpty()) {
                wrapper.like(ProductMaterialFile::getFileName, keyword.trim());
            }

            // 按上传时间倒序排列
            wrapper.orderByDesc(ProductMaterialFile::getUploadTime);
            return productMaterialFileMapper.selectPage(page, wrapper);
        } catch (Exception e) {
            log.error("分页查询用户的产品素材列表失败 - 用户ID: {}", userId, e);
            throw new Exception("分页查询用户的产品素材列表失败: " + e.getMessage());
        }
    }

    @Override
    public void deleteMaterial(Long id) throws Exception {
        log.info("开始删除产品素材记录 - ID: {}", id);

        // 1. 查询数据库记录
        ProductMaterialFile file = productMaterialFileMapper.selectById(id);
        if (file == null) {
            throw new RuntimeException("素材记录不存在");
        }

        // 2. 删除知识库数据集（如果有 datasetId）
        if (file.getDatasetId() != null) {
            try {
                boolean deleted = kbClient.deleteDataset(Collections.singletonList(file.getDatasetId().intValue()));
                log.info("知识库数据集删除结果: {}, datasetId: {}", deleted, file.getDatasetId());
            } catch (Exception e) {
                log.warn("删除知识库数据集失败: {}", e.getMessage(), e);
            }
        }

        // 3. 删除 OSS 文件
        if (StringUtils.isNotBlank(file.getFilePath())) {
            try {
                // 提取 objectName
                String objectName = ossUtil.extractObjectNameFromUrl(file.getFilePath());
                if (StringUtils.isNotBlank(objectName)) {
                    ossUtil.deleteFile(null, objectName);  // bucketName 传 null 使用默认
                    log.info("OSS文件删除成功: {}", objectName);
                } else {
                    log.warn("未能提取出 OSS 文件 objectName，原始路径: {}", file.getFilePath());
                }
            } catch (Exception e) {
                log.warn("删除OSS文件失败: {}", e.getMessage(), e);
            }
        }


        // 4. 删除数据库记录
        productMaterialFileMapper.deleteById(id);
        log.info("数据库记录删除成功 - ID: {}", id);
    }

    @Override
    public List<ProductMaterials> getProductMaterialsByUserId(Long userId) {
        log.info("获取用户产品资料列表 - 用户ID: {}", userId);
        try {
            QueryWrapper<ProductMaterials> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId);
            return mapper.selectList(queryWrapper);
        } catch (Exception e) {
            log.error("获取用户产品资料列表失败 - 用户ID: {}, 错误信息: {}", userId, e.getMessage(), e);
            throw new RuntimeException("获取用户产品资料列表失败", e);
        }
    }

    @Override
    public String getProductMaterialsContentByUserId(Long userId) {
        log.info("获取用户产品资料内容 - 用户ID: {}", userId);
        try {
            // 获取用户的所有产品资料
            List<ProductMaterials> productMaterials = getProductMaterialsByUserId(userId);
            if (productMaterials.isEmpty()) {
                log.info("用户没有产品资料 - 用户ID: {}", userId);
                return "";
            }

            // 合并产品资料内容
            StringBuilder contentBuilder = new StringBuilder();
            for (ProductMaterials material : productMaterials) {
                log.info("开始获取产品资料内容 - 文件名: {}, fileId: {}", 
                        material.getFileName(), material.getFileId());
                try {
                    // 使用agentClient获取知识库中文件的内容
                    // 构建请求payload，包含文件ID信息
                    Payload payload = Payload.builder()
                            .agentId(agentClient.getAgentId())
                            .userChatInput("请提供该文件的详细内容: " + material.getFileName())
                            .files(Collections.singletonList(new Payload.FileInfo(
                                    material.getFileId(), 
                                    material.getFileName(), 
                                    null, 
                                    null)))
                            .build();
                    
                    // 调用Agent服务获取文件内容
                    String fileContent = agentClient.chat_completions(payload);
                    
                    // 检查获取的内容是否有效
                    if (fileContent != null && !fileContent.isEmpty()) {
                        contentBuilder.append("===== 产品资料: ")
                                .append(material.getFileName())
                                .append(" =====\n")
                                .append(fileContent)
                                .append("\n\n");
                        log.info("成功获取产品资料内容 - 文件名: {}, 内容长度: {}", 
                                material.getFileName(), fileContent.length());
                    } else {
                        contentBuilder.append("产品资料: ")
                                .append(material.getFileName())
                                .append(" (无法获取内容)\n");
                        log.warn("未获取到产品资料内容 - 文件名: {}", material.getFileName());
                    }
                } catch (Exception e) {
                    log.error("获取产品资料内容失败 - 文件名: {}, 错误信息: {}", 
                            material.getFileName(), e.getMessage(), e);
                    contentBuilder.append("产品资料: ")
                            .append(material.getFileName())
                            .append(" (获取内容失败)\n");
                }
            }

            log.info("获取用户产品资料内容成功 - 内容长度: {}", contentBuilder.length());
            return contentBuilder.toString();
        } catch (Exception e) {
            log.error("获取用户产品资料内容失败 - 用户ID: {}, 错误信息: {}", userId, e.getMessage(), e);
            throw new RuntimeException("获取用户产品资料内容失败", e);
        }
    }

}